<template>
  <div class="search-wrapper app-container">
    <nav-bar title="搜索" leftArrow />

    <div class="search-container">
      <div class="search-content">
        <icon-svg icon-class="search" />
        <input class="input" v-model="query" @input="search" :placeholder="placeHolder">
        <icon-svg icon-class="error" @click.native="query = ''"/>
      </div>
    </div>

    <scroll class="scroll"
            :style="scrollStyle"
            :data="results"
            :loading="loading"
            pull-up
            :is-open-pull-up="showResults"
            @pullUp="searchMore"
            ref="scroll"
    >
      <results v-if="showResults" :singers="singers" :songs="songs" @select="selectResult" />

      <div v-else>
        <hot-key @select="selectKey" @refresh-scroll="refreshScroll" />
        <history @select="selectKey" ref="history" />
      </div>
    </scroll>

  </div>
</template>

<script>
import { SearchDefaultAsync, SearchAsync } from 'api/search'
import { PlayerMiniRefreshMixin } from 'common/js/mixins'
import { debounce } from 'common/js/utils'
import { createSong } from 'common/js/Song'
import { STORAGE_HISTORY } from 'common/js/constant'
import results from 'views/search/results'
import history from 'views/search/history'
import hotKey from 'views/search/hot-key'
const INPUT_HEIGHT = 64

export default {
  name: 'search',
  mixins: [ PlayerMiniRefreshMixin ],
  data () {
    return {
      placeHolder: '搜索歌名、歌手',
      query: '',

      showResults: false,

      singers: [],
      songs: [],
      loading: false,
      offset: 0,
      limit: 30,
      hasMore: true

    }
  },
  created () {
    this.getSearchDefaultKey()
  },
  activated () {
    if (this.$route.params.query) {
      this.query = this.$route.params.query
      this.search()
    }
  },
  methods: {
    refreshScroll () {
      this.$refs.scroll && this.$refs.scroll.refresh()
    },
    getSearchDefaultKey () {
      SearchDefaultAsync().then(keyWord => {
        this.placeHolder = keyWord
      }).catch(() => {})
    },
    search: debounce(function () {
      this.loading = true
      this.offset = 0
      Promise.all([
        SearchAsync({keywords: this.query, type: 100, offset: 0, limit: 2}),
        SearchAsync({keywords: this.query, type: 1, offset: 0, limit: this.limit})
      ]).then(async (res) => {
        const singers = res[0].artists || []
        const songs = res[1].songs || []
        this.singers = singers
        this.songs = await this.GetSongUrlAsync(songs)
        this.offset++
      }).catch(() => {
        this.loading = false
      })
    }, 500),
    searchMore () {
      this.loading = true
      SearchAsync({keywords: this.query, type: 1, offset: this.offset * this.limit, limit: this.limit}).then(async (res) => {
        const result = res.songs || []
        const songs = await this.GetSongUrlAsync(result)
        this.songs = this.songs.concat(songs)
        this.$refs.scroll.finishPullUp()
        this.offset++
      }).catch(() => {
        this.loading = false
        this.$refs.scroll.finishPullUp()
      })

      this.loading = false
    },
    async GetSongUrlAsync (songs) {
      let ret = []
      let ids = songs.map(item => item.id)
      const urls = await this.$store.dispatch('GetSongUrlAsync', ids)
      this.loading = false
      for (let i = 0; i < songs.length; i++) {
        const urlItem = urls.find(item => item.id === songs[i].id)
        ret.push(createSong({
          ...songs[i],
          ...{url: urlItem.url}
        }))
      }
      return ret
    },

    selectResult () {
      const history = localStorage.getItem(STORAGE_HISTORY) ? localStorage.getItem(STORAGE_HISTORY).split(',') : []
      if (!history.includes(this.query)) {
        history.push(this.query)
        localStorage.setItem(STORAGE_HISTORY, history)
        if (this.$refs.history) this.$refs.history.getHistory()
      }
    },
    selectKey (key) {
      this.query = key
      this.search()
    }
  },
  watch: {
    query: debounce(function (value) {
      this.showResults = !!value
      this.refreshScroll()
    }, 500)
  },
  computed: {
    results () {
      return this.singers.concat(this.songs)
    },
    scrollStyle () {
      return {
        top: this.$store.state.StatusBarHeight + this.$config.nav_bar_height + INPUT_HEIGHT + 'px',
        bottom: this.$store.state.player.playList.length ? this.$config.player_mini_height + 'px' : 0
      }
    }
  },
  components: { results, hotKey, history }
}
</script>

<style scoped lang="less">
  @import "~common/style/variable.less";
  @import "~common/style/mixins.less";

  .search-container {
    margin: 12px;
    .search-content {
      width: 100%;
      height: 40px;
      display: flex;
      background: @color-background-d;
      align-items: center;
      border-radius: 5px;
      svg {
        padding: 8px;
        font-size: @font-size-large;
        color: @color-text-d;
      }
      .input {
        flex: 1;
        font-size: @font-size-medium;
        background: transparent;
      }
    }
  }

  .scroll {
    position: absolute;
    left: 0;
    right: 0;
    overflow: hidden;
  }
</style>
